package models

import (
	"github.com/gin-contrib/multitemplate"
	"github.com/gin-gonic/gin"
	"log"
	"path/filepath"
	"reflect"
	"strings"
)

var Router *gin.Engine

func init(){
	Router = getRouter()
}
func getRouter() *gin.Engine {
	var (
		baseRouter *gin.Engine
		render multitemplate.Renderer
	)
	baseRouter = gin.New()
	render = loadTemplates("./templates")
	baseRouter.HTMLRender = render
	baseRouter.Static("/static","./statics/layui")
	baseRouter.GET("/exec", exec)
	baseRouter.POST("/exec", exec)
	return baseRouter
}

func exec(c *gin.Context){
	var (
		funcName   string
		structName interface{}
		method     reflect.Method
		ok         bool
		params     []reflect.Value
	)
	funcName = c.Query("f")                      //获取请求参数中的方法名
	if structName = getDefinedTypeByFuncName(funcName);structName == nil{
		c.HTML(403,"403",nil)
		return
	} //根据方法名取对应的自定义结构	用于根据方法名取方法

	if method, ok = reflect.TypeOf(structName).MethodByName(funcName); !ok {
		c.HTML(403,"403",nil)
	} else {
		params = []reflect.Value{
			reflect.ValueOf(structName),
			reflect.ValueOf(c),
		}
		method.Func.Call(params)
	}
}
func getDefinedTypeByFuncName(funcName string)interface{}{
	var prifexText string
	prifexText = string([]rune(funcName)[0:4])
	switch prifexText {
	//stable map
	case "SMFC":
		return new(StableMap)
	//npc
	case "NPFC":
		return new(Npc)
	//monster
	case "MOFC":
		return new(Monster)
	//page
	case "PGFC":
		return new(PAGE)
	//api
	case "APFC":
		return new(API)
	default:
		return nil
	}
}

func loadTemplates(templatesDir string) multitemplate.Renderer {
	r := multitemplate.NewRenderer()
	layouts, err := filepath.Glob(templatesDir + "/layouts/*.html")
	if err != nil {
		log.Fatal(err)
	}
	extends, err := filepath.Glob(templatesDir + "/extendTemps/**/*.html")
	if err != nil {
		log.Fatal(err)
	}
	unextends,err := filepath.Glob(templatesDir + "/unextendTemps/**/*.html")
	if err != nil {
		log.Fatal(err)
	}
	for _,unextend := range unextends{
		r.AddFromFiles(strings.Split(filepath.Base(unextend),".")[0],unextend)
	}
	// 为layouts/和includes/目录生成 templates map
	for _, extend := range extends {
		layoutCopy := make([]string, len(layouts))
		copy(layoutCopy, layouts)
		files := append(layoutCopy, extend)
		r.AddFromFiles(strings.Split(filepath.Base(extend),".")[0], files...)
	}
	return r
}

